﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.VisualStudio.Modeling;

namespace Project.Co_DataTransformationPrototype
{
    
    /// <summary>
    /// Class contains an extension method for the TreeView & TreeNodeCollection class
    /// </summary>
    static class TreeRelatedExtensions
    {
        private static TreeNodeCollection trvRootNodes;
        private delegate void AddNodeToTree(string itemKey, string itemValue);
        private delegate void AddListToTree(string itemKey, string elementKey, IList<EventContext> value);
        

        public static void AddDataSource(this TreeView trvControl, IDictionary<Guid, ElementEventInfo> data)
        {
            const string EventKeyString = "EntityEvents";
            const string AttributeKeyString = "AttributesEvents";
            const string LinkKeyString = "LinkEvents";

            string strEntityName = string.Empty;

            foreach (System.Collections.Generic.KeyValuePair<Guid, ElementEventInfo> item in data)
            {
                if (trvControl.Nodes.ContainsKey(item.Key.ToString()))
                {
                    // Clear sub-tree's and update tree root label if needed
                    trvControl.Nodes[item.Key.ToString()].Nodes[EventKeyString].Nodes.Clear();
                    trvControl.Nodes[item.Key.ToString()].Nodes[AttributeKeyString].Nodes.Clear();
                    trvControl.Nodes[item.Key.ToString()].Nodes[LinkKeyString].Nodes.Clear();
                    trvControl.Nodes[item.Key.ToString()].Text = item.Value.MainEntityName;
                }
                else
                {
                    // Build tree root and it's sub-trees
                    if (trvControl.InvokeRequired)
                    {
                        trvRootNodes = trvControl.Nodes;
                        trvControl.Invoke(new AddNodeToTree(addNodeToTree), new object[] { item.Key.ToString(), item.Value.entityEvent[0].entityName });
                        trvRootNodes = trvControl.Nodes[item.Key.ToString()].Nodes;
                        trvControl.Invoke(new AddNodeToTree(addNodeToTree), new object[] { EventKeyString, "Entity Events" });
                        trvControl.Invoke(new AddNodeToTree(addNodeToTree), new object[] { AttributeKeyString, "Attribute Events" });
                        trvControl.Invoke(new AddNodeToTree(addNodeToTree), new object[] { LinkKeyString, "Link Events" });
                        trvControl.Update();
                    }
                    else
                    {
                        TreeNode node = new TreeNode(item.Value.MainEntityName);
                        node.Name = item.Key.ToString();
                        trvControl.Nodes.Add(node);
                        trvControl.Nodes[node.Name].Nodes.Add(EventKeyString, "Entity Events");
                        trvControl.Nodes[node.Name].Nodes.Add(AttributeKeyString, "Attribute Events");
                        trvControl.Nodes[node.Name].Nodes.Add(LinkKeyString, "Link Events");
                    }
                }

                // Add events to their respective subtree
                if (trvControl.InvokeRequired)
                {
                    trvRootNodes = trvControl.Nodes;
                    trvControl.Invoke(new AddListToTree(addListToTree), new object[] { item.Key.ToString(), EventKeyString, item.Value.entityEvent });
                    trvControl.Invoke(new AddListToTree(addListToTree), new object[] { item.Key.ToString(), AttributeKeyString, item.Value.attributeEvent });
                    trvControl.Invoke(new AddListToTree(addListToTree), new object[] { item.Key.ToString(), LinkKeyString, item.Value.linkEvent });
                    trvControl.Update();
                }
                else
                {
                    trvControl.Nodes[item.Key.ToString()].Nodes[EventKeyString].Nodes.ListToNodeCollection(item.Value.entityEvent);
                    trvControl.Nodes[item.Key.ToString()].Nodes[AttributeKeyString].Nodes.ListToNodeCollection(item.Value.attributeEvent);
                    trvControl.Nodes[item.Key.ToString()].Nodes[LinkKeyString].Nodes.ListToNodeCollection(item.Value.linkEvent);
                }
            }
        }

        /// <summary>
        /// Adds each element in list (input) to the TreeNodeCollection object
        /// </summary>
        /// <param name="treeNodeCollection"></param>
        /// <param name="input"></param>
        public static void ListToNodeCollection(this TreeNodeCollection treeNodeCollection, IList<EventContext> input)
        {
            foreach (EventContext eventContext in input)
            {
                treeNodeCollection.Add(eventContext.actionText);
            }
        }

        private static void addNodeToTree(string nodeKey, string nodeName)
        {
            trvRootNodes.Add(nodeKey, nodeName);
        }

        private static void addListToTree(string itemKey, string elementKey, IList<EventContext> nodeList)
        {
            trvRootNodes[itemKey].Nodes[elementKey].Nodes.ListToNodeCollection(nodeList);
        }

    }
}
